package org.atlantis.net.base.frame;

/*
 * 长度区分法的成帧，解帧实现。
 */
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class LengthFramer implements Framer {

	public static final int MAXMESSAGELENGTH = 65535;
	public static final int BYTEMASK = 0xFF;
	public static final int SHORTMASK = 0xFFFF;
	public static final int BYTESHIFT = 8;

	private DataInputStream in;

	public LengthFramer(InputStream in) {
		this.in = new DataInputStream(in);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.atlantis.net.base.frame.Framer#frameMessage(byte[],
	 * java.io.OutputStream)
	 */
	@Override
	public void frameMessage(byte[] message, OutputStream out)
			throws IOException {
		if (message.length > MAXMESSAGELENGTH) {
			throw new IOException("message too long.");
		}

		// 标记长度前缀
		out.write((message.length >> BYTESHIFT) & BYTEMASK);
		out.write(message.length & BYTEMASK);
		// 填充信息数据
		out.write(message);
		out.flush();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.atlantis.net.base.frame.Framer#nextMessage()
	 */
	@Override
	public byte[] nextMessage() throws IOException {
		int length;
		try {
			length = in.readUnsignedShort(); // 读取2个字节（头两个字节表示长度）
		} catch (EOFException e) {
			return null;
		}
		byte[] message = new byte[length];
		in.readFully(message);
		return message;
	}
}
